import SockJS from  'sockjs-client/dist/sockjs.min.js';
import  Stomp from 'stompjs';
import website from '@/config/website';
import {getToken} from "@/utils/auth";

class SocketUtil {
  /**
   * 开始debug
   * @type {boolean}
   */
  static debug = false;
  /**
   * 重连计时器 （5秒）
   * @type {number}
   */
  static RE_CONNECT_TIME = 10 * 1000;
  static RE_CONNECT_COUNT = 3;
  /**
   * 每段时间发送一次心跳包 这里设置为20s
   * @type {number}
   */
  static HEART_TIMEOUT = 20 * 1000;
  /**
   * 心跳发送/返回的信息 服务器和客户端收到的信息内容如果如下 就识别为心跳信息 不要做业务处理
   * @type {string}
   */
  static CHECK_MSG = "heartbeat";
  /**
   * 打印日志
   * @param msg
   */
  static log(...msg) {
    if (SocketUtil.debug) {
      console.log(...msg)
    }
  }
}

export class IMScoketJS {
  constructor(options = {}) {
    this.options = Object.assign({
      autoConnect: true,
      maxWebSocketFrameSize: 2 * 1024 * 1024,
      // 地址
      ws: ""
      // 消息接收
      ,onConnectedListener: (stompClient, headers)=> {}
      // 链接错误
      ,onConnectErrorListener: (error)=> {}
      // 消息接收
      ,disconnect: ()=> {},
      /**
       * 重连
       * @param count
       * @param totalCount
       */
      onReConnectListener: (count, totalCount) => {}
    }, options);
    this.timer = null;
    this.timerCount = 0;
    this.stompClient = null;
    this.headers = {};
    // this.initWebSocket();
  }

  initWebSocket() {
    this.disconnect();
    this.connection();
    let that= this;
    // // 断开重连机制,尝试发送消息,捕获异常发生时重连
    // this.timer = setInterval(() => {
    //   try {
    //     that.stompClient.send("test");
    //   } catch (err) {
    //     console.log("断线了: " + err);
    //     that.connection();
    //   }
    // }, SocketUtil.RE_CONNECT_TIME);
  }

  connection() {
    SocketUtil.log("链接地址");
    if (!this.options.ws) {
      return new Error("地址不能为null")
    }
    // 建立连接对象
    let socket = new SockJS(this.options.ws);
    // 获取STOMP子协议的客户端对象
    this.stompClient = Stomp.over(socket);
    this.stompClient.maxWebSocketFrameSize = this.options.maxWebSocketFrameSize;
      // 定义客户端的认证信息,按需求配置
    this.headers = {
      // Authorization:''
      [website.tokenHeader]: 'bearer ' + getToken()
    };
    // 向服务器发起websocket连接
    this.stompClient.connect(this.headers,() => {
      SocketUtil.log('连接成功');
      if (this.options.onConnectedListener) {
        this.options.onConnectedListener(this.stompClient, this.headers)
      }
      // this.stompClient.subscribe('/topic/public', (msg) => { // 订阅服务端提供的某个topic
      //   console.log('广播成功')
      //   console.log(msg);  // msg.body存放的是服务端发送给我们的信息
      // },headers);
      // this.stompClient.send("/app/chat.addUser",
      //   headers,
      //   JSON.stringify({sender: '',chatType: 'JOIN'}),
      // )   //用户加入接口
    }, (err) => {
      // 连接发生错误时的处理函数
      SocketUtil.log(err);
      if (this.options.onConnectErrorListener) {
        this.options.onConnectErrorListener(err)
      }
      const _this = this;
      if (this.options.autoConnect) {
        this.timer = setTimeout(() => {
          const isReconnect = _this.timerCount < SocketUtil.RE_CONNECT_COUNT;
          if (isReconnect) {
            _this.connection();
            _this.timerCount ++
          } else {
            _this.closeReconect()
          }
          if (_this.options.onReConnectListener) {
            _this.options.onReConnectListener(isReconnect, _this.timerCount, SocketUtil.RE_CONNECT_COUNT, SocketUtil.RE_CONNECT_TIME)
          }
        }, SocketUtil.RE_CONNECT_TIME);
      }
    });
  }

  closeReconect() {
    if (this.timer) {
      window.clearTimeout(this.timer);
      this.timer = null;
      this.timerCount = 0;
    }
  }

  send(api, message, headers) {
    if (this.stompClient) {
      this.stompClient.send(api,
        // headers || this.headers,
        headers || {
          [website.tokenHeader]: 'bearer ' + getToken()
        },
        JSON.stringify(message),
      )
    }
  }

  //连接 后台
  disconnect() {
    if (this.stompClient) {
      this.closeReconect(this.timer);
      this.stompClient.disconnect();
      if (this.options.disconnect) {
        this.options.disconnect()
      }
    }
  }

  getClient() {
    return this.stompClient;
  }

}
